//! stvec寄存器0x105用来保存S模式下配置异常向量表入口地址和异常访问模式。

use core::arch::asm;

#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Stvec {
    bits: usize,
}
impl Stvec {
    pub const BITMASK: usize = usize::MAX;

    pub const fn from_bits(bits: usize) -> Self {
        Self {
            bits: bits & usize::MAX,
        }
    }

    pub const fn bits(&self) -> usize {
        self.bits & usize::MAX
    }

    pub const fn bitmask(&self) -> usize {
        Self::BITMASK
    }
}

#[inline(always)]
unsafe fn _read() -> usize {
    let r: usize;
    unsafe {
        asm!(
            "csrrs {0}, 0x105, zero",
            out(reg)r
        );
    }
    r
}

#[inline]
pub fn read() -> Stvec {
    Stvec {
        bits: unsafe { _read() },
    }
}

#[inline(always)]
unsafe fn _write(bits: usize) {
    unsafe {
        asm!(
            "csrrw zero, 0x105, {0}",
            in(reg) bits,
        );
    }
}

#[inline]
pub fn write(value: Stvec) {
    unsafe {
        _write(value.bits);
    }
}
